package com.ittx.dzt.meituan.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.ittx.dzt.edi.constant.PlatformApiConstant;
import com.ittx.dzt.edi.constant.PlatformMessageConstant;
import com.ittx.dzt.edi.dto.PlatformApiParamDTO;
import com.ittx.dzt.edi.vo.ResponseMessageVO;
import com.ittx.dzt.meituan.constant.MeituanApiConstant;
import com.ittx.dzt.meituan.handler.AbstractMeituanByTimeApiHandler;
import com.ittx.dzt.meituan.util.CyUtil;
import com.ittx.dzt.sys.response.Result;
import lombok.extern.slf4j.Slf4j;
import open.dto.TimeFrameDto;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.ZoneOffset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 增量下载订单
 *
 * @author gywang
 * @since 2024-08-01
 */
@Slf4j
@Service
public class MeituanSalesOrderDownloadByTimeService extends AbstractMeituanByTimeApiHandler<TimeFrameDto> {


    @Autowired
    private MeituanSalesOrderDownloadByIdService meituanSalesOrderDownloadByIdService;


    @Override
    protected String getMqTopic() {
        return MeituanApiConstant.Rocket.MEITUAN_DOWNLOAD_ORDER_SEARCHLIST_BY_TIME_BATCH_SPLIT_TOPIC;
    }

    @Override
    public String getMeituanMethod() {
        return MeituanApiConstant.ORDER_LIST;
    }

    @Override
    public String getHttpMethod() {
        return MeituanApiConstant.ApiHttpMethod.POST;
    }

    @Override
    public String getLocalApiMethod() {
        return open.constant.PlatformApiConstant.InboundInterface.SALESORDER_DOWNLOAD_BY_TIMEFRAME;
    }

    @Override
    protected Result<?> doProcessByNormalType(PlatformApiParamDTO platformApiParamDTO, TimeFrameDto timeFrameDTO) {
        //分发数据,异步下载
        Map<String, Boolean> logMap = new HashMap<>();
        return this.requestListBySdk(platformApiParamDTO, timeFrameDTO, logMap);
    }

    @Override
    protected Result<?> doProcessByCheckType(PlatformApiParamDTO platformApiParamDTO, TimeFrameDto timeFrameDTO) {
        //探查成功时不返回完整数据,只返回数量
        return this.requestListBySdk(platformApiParamDTO, timeFrameDTO, null);
    }

    @Override
    protected Result<?> doProcessByIdType(PlatformApiParamDTO platformApiParamDTO, TimeFrameDto timeFrameDTO) {
        String orderId = platformApiParamDTO.getPlatformIdentifierTag();
        return this.asyncHandlerById(platformApiParamDTO, orderId);
    }

    private Result<?> requestListBySdk(PlatformApiParamDTO platformApiParamDTO, TimeFrameDto timeFrameDTO, Map<String, Boolean> logMap) {
        String status = CyUtil.getStatusStr(platformApiParamDTO, "sale");
        if (StringUtils.isBlank(status))
            return requestListBySdk(platformApiParamDTO, timeFrameDTO, logMap, "1");
        for (String s : status.split(",")) {
            Result result = requestListBySdk(platformApiParamDTO, timeFrameDTO, logMap, s);
            if (!result.isSuccess())
                return result;
        }
        return Result.success(logMap);
    }

    /**
     * sdk
     * 请求平台接口
     */
    private Result<?> requestListBySdk(PlatformApiParamDTO platformApiParamDTO, TimeFrameDto timeFrameDTO, Map<String, Boolean> logMap, String status) {
        Map<String, String> params = new HashMap<>();
        params.put("poi_id", getPoIId(platformApiParamDTO));
        params.put("start_time", timeFrameDTO.getFrom().toEpochSecond(ZoneOffset.of("+8")) + "");
        params.put("end_time", timeFrameDTO.getTo().toEpochSecond(ZoneOffset.of("+8")) + "");
        params.put("status", status);
        String nextToken = null;
        do {
            Result<?> result = this.executeMeituanApi(platformApiParamDTO.getStoreConfig(), params, platformApiParamDTO.getRequestId());
            if (!result.isSuccess()) {
                return result;
            }
            Map<String, Object> resultMap = (Map<String, Object>) result.getData();
            Map<String, Object> dataMap = (Map<String, Object>) resultMap.get(DATA_FIELD);
            List<Map<String, Object>> list = (List<Map<String, Object>>) dataMap.get("order_list");
            nextToken = (String) dataMap.get("cursor");
            Boolean hasNext = (Boolean) dataMap.get("has_next");
            //不能根据分页游标cursor判断是否有下一页，要根据has_next判断
            if (hasNext == null || !hasNext)
                nextToken = null;
            // 订单数量
            int total = list.size();
            if (StringUtils.isNotBlank(nextToken))
                total++;
            // 探查模式只返回总数
            if (PlatformApiConstant.ApiByTime.CHECK.equals(platformApiParamDTO.getQueryType())) {
                return Result.success().addData(total);
            }
            if (CollectionUtil.isNotEmpty(list)) {
                // 分发数据到MQ，异步消费下载
                for (Map<String, Object> order : list) {
                    String orderId = order.get("order_view_id").toString();
                    sendToSplitTopic(platformApiParamDTO, orderId, logMap);
                }
            }
        } while (StringUtils.isNotBlank(nextToken));

        return Result.success(logMap);
    }

    /**
     * sdk
     * 根据单号查询单条订单信息-- 多线程执行
     */
    @Override
    public Result<?> asyncHandlerById(PlatformApiParamDTO platformApiParamDTO, String orderId) {
        Result<?> result = meituanSalesOrderDownloadByIdService.getOrderById(platformApiParamDTO, orderId);
        if (!result.isSuccess()) {
            return result;
        }
        return this.sendRequestToPlatform(platformApiParamDTO, result.getData(), true);
    }

    /**
     * 参数校验
     *
     * @param platformApiParamDTO 平台请求参数
     * @param timeFrameDTO        接口请求参数
     */
    public Result<?> checkParams(PlatformApiParamDTO platformApiParamDTO, TimeFrameDto timeFrameDTO) {
        if (timeFrameDTO == null || platformApiParamDTO.getStoreConfig() == null ||
                timeFrameDTO.getTo() == null || timeFrameDTO.getFrom() == null) {
            String msg = StrUtil.format(PlatformMessageConstant.MSG_PLAT_0004_MSG, platformApiParamDTO.getRequestId(),
                    this.getPlatformCode(), getLocalApiMethod(), timeFrameDTO);
            log.error(msg);
            return Result.error(new ResponseMessageVO(PlatformMessageConstant.MSG_PLAT_0004, msg));
        }
        return Result.success();
    }
}
